<?php
/**
 * Created by PhpStorm.
 * User: joe
 * Date: 17-10-31
 * Time: 下午2:08
 */

namespace System;


class Upload {

    // strings
    private $language;
    // protocol http / https
    private $protocol;
    // upload status
    private $uploaded = false;
    // this file specs
    private $file_extension;
    private $field_name;
    private $file_name;
    private $real_name;
    private $file_type;
    private $file_tmp_name;
    private $file_size_bytes;
    // upload directory
    private $dir;
    // errors/warnings array
    private $errors   = [];
    private $warnings = [];
    // default allowed extentions
    private $allowed_extensions = '*';

    // allowed file size in Bytes
    private $allowed_size_bytes;

    function __construct($field_name = null, $dir = "./", $max_size_mb = 1024, $allowed_extensions = null) {
        $this->get_language();
        if ($max_size_mb < 2000 && $max_size_mb != null && $max_size_mb != "") {

            $this->allowed_size_bytes = $this->to_byte($max_size_mb);
        } else {
            array_push($this->errors, $this->language->input_size_error);
        }
        if ($field_name && isset($_FILES[$field_name])) {
            $this->set_file_specs($field_name);
        } else {
            array_push($this->errors, $this->language->field_error . json_encode($_FILES));
        }
        if ($dir && is_dir($dir)) {
            $this->dir = $dir;
        } else {
            array_push($this->errors, $this->language->upload_dir_error);
        }

        if (is_array($allowed_extensions) and $allowed_extensions != "" and $allowed_extensions != null) {
            $this->allowed_extensions = $allowed_extensions;
        }
    }

    public function setAllowedExtension($allowed) {
        $this->allowed_extensions = $allowed;
    }

    private function get_language() {
        $this->language = new \System\Language('zh_CN', 'system/upload');
    }

    private function set_file_specs($field_name) {
        if (!empty($_FILES[$field_name]['name'])) {
            $this_file_ref = $_FILES[$field_name];
            $this->field_name = $field_name;
            $this->file_tmp_name = $this_file_ref['tmp_name'];
            $this->file_name = $this_file_ref['name'];
            $this->file_type = mime_content_type($this->file_tmp_name);
            $this->file_size_bytes = $this_file_ref['size'];
            $this->file_extension = pathinfo($this->file_name)['extension'];
            $this->real_name = md5($this->file_name) . '.' . $this->file_extension;
        } else {
            array_push($this->warnings, $this->language->file_not_selected_war);
        }
    }

    private function to_byte($mb) {
        return $mb * 1048576;
    }

    private function to_mb($bytes) {
        return $bytes / 1048576;
    }

    private function validate_size() {
        if ($this->allowed_size_bytes < $this->file_size_bytes) {
            array_push($this->warnings, $this->language->max_size_war);
            return false;
        }
        return true;
    }

    private function validate_extension() {
        if ($this->allowed_extensions == "*") {
            return true;
        } else if (!in_array($this->file_extension, $this->allowed_extensions)) {
            array_push($this->warnings, $this->language->invalid_file_extension);
            return false;
        }
        return true;
    }

    private function check_file() {
        if (file_exists($this->dir . $this->real_name)) {
            array_push($this->errors, $this->language->file_is_exists);
            return false;
        }
        return true;
    }

    public function do_upload() {
        if (empty($this->errors) && empty($this->warnings) && $this->validate_size() && $this->validate_extension() && $this->check_file()) {
            $this->uploaded = move_uploaded_file($this->file_tmp_name, $this->dir . $this->real_name);
            if ($this->uploaded) {
                return true;
            }
            array_push($this->errors, $this->language->unknown_problem);
            return false;
        }
        return false;
    }

    public function file() {
        $config = new Config('Mimetype');
        $file = [
            'file_name' => $this->file_name,
            'real_name' => $this->real_name,
            'mime' => $this->file_type,
            'type' => isset($config->mime[$this->file_type]) ? $config->mime[$this->file_type] : '',
            'path' => $this->dir,
            'ext' => $this->file_extension,
            'size' => $this->to_mb($this->file_size_bytes)
        ];
        return ($this->uploaded) ? $file : null;
    }

    public function file_url() {
        if ($this->uploaded) {
            if (isset($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on") {
                $this->protocol .= "https";
            } else {
                $this->protocol .= "http";
            }
            return $this->protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $this->dir . $this->file_name;
        }
        return false;
    }

    public function errors() {
        if (empty($this->errors) and empty($this->warnings)) {
            return false;
        }
        return array_merge($this->errors, $this->warnings);
    }
}